#!/usr/bin/python3

import math
import time

import pyglet
from pyglet import clock
from pyglet import shapes
from pyglet.text import Label
from pyglet.window import key, mouse


class Window(pyglet.window.Window):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._color = 1
        self.scale = 10
        self.obj_text = '[空]'
        self.dist = 'N.A. '
        self.show_inner = False
        self.start = True
        # 数据来自 https://zh.wikipedia.org/wiki/太阳系#太阳与八大行星数据表
        # 单位: 天文单位(AU)
        self._objs = {
                    '水星': 0.3871,
                    '金星': 0.7233,
                    '地球': 1.0,
                    '火星': 1.5237,
                    '木星': 5.2026,
                    '土星': 9.5549,
                    '天王星': 19.2184,
                    '海王星': 30.1141,
            }
        self.start_elements = [
                Label('太阳系', font_size=40, x=400, y=320, anchor_x='center'),
                Label('The Solar System', font_size=20, x=400, y=280, anchor_x='center'),
            ]
        self.labels = [
                    Label('%sAU' % self.dist, font_size=20, x=790, y=40, anchor_x='right', align='right'),
                    Label(self.obj_text, font_size=20, x=790, y=10, anchor_x='right', align='right'),
                    Label(time.strftime('%Y年\n%m月%d日\n%H: %M: %S'), font_size=20, x=790, y=self.height - 30,
                        anchor_x='right', align='right', multiline=True, width=self.width - 620),
            ]
        clock.schedule_once(self.starts, 0.01)

    def draw_objs(self):
        shapes.Line(310, 310 - 1, 310, 310 + 1, width=2, color=(255, 255, 0)).draw()
        shapes.Line(620, 5, 620, self.height - 5, color=(255, ) * 3).draw()
        if not self.show_inner:
            shapes.Line(310, 310 - 1, 310, 310 + 1, width=2, color=(255, 255, 0)).draw()
            for r in self._objs.values():
                shapes.Arc(310, 310, r * self.scale, color=self.get_color()).draw()
            self._color = 1
        else:
            for r in self._objs.values():
                if (r * self.scale <= 310):
                    shapes.Arc(310, 310, r * self.scale, color=self.get_color()).draw()
            self._color = 1

    def get_color(self):
        if self._color == 1:
            self._color = 0
            return (0, 0, 255)
        else:
            self._color = 1
            return (255, 0, 0)

    def on_draw(self):
        self.clear()
        if self.start:
            for element in self.start_elements:
                element.draw()
        else:
            self.draw_objs()
            self.labels[0].text = '%sAU' % self.dist
            self.labels[1].text = self.obj_text
            self.labels[2].text = time.strftime('%Y年\n%m月%d日\n%H: %M: %S')
            for label in self.labels:
                label.draw()

    def on_mouse_motion(self, x, y, dx, dy):
        y = self.height - y
        self.dist = round(math.dist((310, 310), (x, y)) / self.scale, 2)
        if (x >= 620):
            self.dist = 'N.A. '
        if not self.show_inner:
            if 0 < math.dist((310, 310), (x, y)) < 20:
                self.obj_text = '内行星'
                return
        for objs, r in self._objs.items():
            if (r * self.scale - 5) < math.dist((310, 310), (x, y)) < (r * self.scale + 5):
                self.obj_text = objs + '轨道'
                return
        self.obj_text = '[空]'

    def on_key_press(self, symbol, modifiers):
        if symbol == key.ESCAPE:
            self.close()
        elif (symbol == key.X) or (symbol == key.TAB):
            self.toggle_inner()

    def starts(self, dt):
        if (self.start_elements[0].color[-1] <= 5):
            clock.schedule_once(self.starts, 0.1)
            self.start = False
        else:
            color_A = int(self.start_elements[0].color[3] - dt * 85)
            for label in self.start_elements[:2]:
                label.color = (255, 255, 255, color_A)
            clock.schedule_once(self.starts, 0.01)
    
    def toggle_inner(self):
        self.show_inner = not self.show_inner
        if self.show_inner:
            self.scale = 300 / self._objs['火星']
            self.set_caption('内太阳系')
        else:
            self.set_caption('太阳系')
            self.scale = 10


if __name__ == '__main__':
    win = Window(800, 620, '太阳系')
    pyglet.app.run()
